﻿using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

namespace Zero.UControl.Base.Helper
{
    public static class ImageHelper
    {
        /// <summary>
        /// 将 Bitmap 转为 BitmapSource
        /// </summary>
        public static BitmapSource BitmapToBitmapSource(Bitmap bitmap)
        {
            if (bitmap == null) throw new ArgumentNullException(nameof(bitmap));
            var hBitmap = bitmap.GetHbitmap();
            try
            {
                return Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                NativeMethods.DeleteObject(hBitmap);
            }
        }

        /// <summary>
        /// 将 BitmapSource 转为 Bitmap（通用方式，使用 MemoryStream）
        /// </summary>
        public static Bitmap BitmapSourceToBitmap(BitmapSource source)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));

            using (var stream = new MemoryStream())
            {
                var encoder = new PngBitmapEncoder(); // 可替换为 JpegBitmapEncoder 等
                encoder.Frames.Add(BitmapFrame.Create(source));
                encoder.Save(stream);
                return new Bitmap(stream);
            }
        }

        /// <summary>
        /// 将 Image 转为 BitmapSource
        /// </summary>
        public static BitmapSource ImageToBitmapSource(Image image)
        {
            if (image == null) throw new ArgumentNullException(nameof(image));
            using (var bitmap = new Bitmap(image))
            {
                return BitmapToBitmapSource(bitmap);
            }
        }

        /// <summary>
        /// 将 BitmapSource 转为 Image
        /// </summary>
        public static Image BitmapSourceToImage(BitmapSource source)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));
            var bmp = BitmapSourceToBitmap(source);
            return new Bitmap(bmp); // 返回 Image 类型
        }

        /// <summary>
        /// 将 Image 转为 Bitmap
        /// </summary>
        public static Bitmap ImageToBitmap(Image image)
        {
            if (image == null) throw new ArgumentNullException(nameof(image));
            return new Bitmap(image);
        }

        /// <summary>
        /// 将 Bitmap 转为 Image
        /// </summary>
        public static Image BitmapToImage(Bitmap bitmap)
        {
            if (bitmap == null) throw new ArgumentNullException(nameof(bitmap));
            return (Image)bitmap.Clone();
        }

        /// <summary>
        /// 获取图像的通道数（如：灰度为1，RGB为3，ARGB为4）
        /// </summary>
        public static int GetChannelCount(Bitmap bitmap)
        {
            if (bitmap == null) throw new ArgumentNullException(nameof(bitmap));
            switch (bitmap.PixelFormat)
            {
                case PixelFormat.Format8bppIndexed: return 1;
                case PixelFormat.Format24bppRgb: return 3;
                case PixelFormat.Format32bppArgb:
                case PixelFormat.Format32bppPArgb:
                case PixelFormat.Format32bppRgb: return 4;
                case PixelFormat.Format16bppGrayScale: return 1;
                default:
                    throw new NotSupportedException($"Unsupported pixel format: {bitmap.PixelFormat}");
            }
        }

        /// <summary>
        /// 获取 BitmapSource 的通道数（通过 BitsPerPixel 计算）
        /// </summary>
        public static int GetChannelCount(BitmapSource source)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));
            int bitsPerPixel = source.Format.BitsPerPixel;
            return bitsPerPixel / 8; // 通常1字节=1通道
        }

        public static BitmapSource DeepCopyBitmapSource(BitmapSource source)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));

            // 创建一个新的 WriteableBitmap，尺寸与格式一致
            var wb = new WriteableBitmap(source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, source.Format, source.Palette);

            // 计算 stride（每一行占用的字节数）
            int stride = (source.PixelWidth * source.Format.BitsPerPixel + 7) / 8;

            // 创建像素缓存区
            byte[] pixels = new byte[stride * source.PixelHeight];

            // 复制像素数据
            source.CopyPixels(pixels, stride, 0);

            // 写入到新 Bitmap 中
            wb.WritePixels(new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), pixels, stride, 0);

            return wb;
        }

        /*
           通过自定义方式填写图标文件头信息并嵌入原始图像数据的方法，可以生成更加清晰、准确反映原图的图标文件
                预留：地址00-01（设置为0）
                类型：地址02-03（值为1表示ICO格式）
                图片数量：地址04-05（默认为1）
                图像宽高：地址06-07（例如16x16, 32x32等）
                颜色数量：地址08（如果色深>=8bpp，则设置为0）
                预留：地址09（设置为0）
                颜色平面：地址10-11（默认为1）
                数据大小：地址14-17（图像数据长度）
                数据偏移：地址18-21（通常设置为22）
         */
        public static void ConvertToIcon(string imagePath, string outputPath, byte size = 128)
        {
            using (Image srcImage = Image.FromFile(imagePath))
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    // 写入ICO文件头
                    stream.Write(new byte[] { 0, 0 }, 0, 2); // 预留字
                    stream.Write(new byte[] { 1, 0 }, 0, 2); // 类型(1=ICO)
                    stream.Write(new byte[] { 1, 0 }, 0, 2); // 图像数量
                    int dataOffset = 6 + 16; // 数据偏移

                    using (Image newImg = new Bitmap(srcImage, new System.Drawing.Size(size, size)))
                    {
                        byte[] imgData = null;
                        using (MemoryStream imageStream = new MemoryStream())
                        {
                            newImg.Save(imageStream, ImageFormat.Png);
                            imgData = imageStream.ToArray();
                        }

                        // 设置图标宽度、高度
                        stream.Write(new byte[] { size, size }, 0, 2);
                        stream.Write(new byte[] { 0, 0 }, 0, 2); // 颜色数、预留字
                        stream.Write(new byte[] { 1, 0 }, 0, 2); // 颜色平面
                        stream.Write(new byte[] { 32, 0 }, 0, 2); // 每像素位数
                        stream.Write(BitConverter.GetBytes(imgData.Length), 0, 4); // 图像数据大小
                        stream.Write(BitConverter.GetBytes(dataOffset), 0, 4); // 数据偏移
                        stream.Write(imgData, 0, imgData.Length); // 写入图像数据

                        File.WriteAllBytes(outputPath, stream.ToArray());
                    }
                }
            }
        }

        public static void ConvertToPng(string inputPath, string outputPath)
        {
            // 要变成透明的颜色（以白色为例）
            Color transparentColor = Color.White;

            // 加载图像
            using (Bitmap original = new Bitmap(inputPath))
            // 创建 32位支持透明通道的新图像
            using (Bitmap transparent = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb))
            {
                // 设置每个像素
                for (int y = 0; y < original.Height; y++)
                {
                    for (int x = 0; x < original.Width; x++)
                    {
                        Color pixel = original.GetPixel(x, y);
                        // 如果是目标颜色，设为透明
                        if (pixel.ToArgb() == transparentColor.ToArgb())
                            transparent.SetPixel(x, y, Color.FromArgb(0, pixel)); // 完全透明
                        else
                            transparent.SetPixel(x, y, pixel);
                    }
                }
                // 保存为带透明通道的 PNG
                transparent.Save(outputPath, ImageFormat.Png);
            }
        }

        public static void DelObject(IntPtr intPtr)
        {
            NativeMethods.DeleteObject(intPtr);
        }

        public static class NativeMethods
        {
            [DllImport("gdi32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DeleteObject(IntPtr hObject);
        }
    }
}
